home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Online / hsc / source / hsctools / hscpitt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-02  |  21.5 KB  |  931 lines

  1. /*
  2.  * This source code is part of hsc, a html-preprocessor,
  3.  * Copyright (C) 1995-1997  Thomas Aglassinger
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20. /*
  21.  * hscpitt
  22.  *
  23.  * hsc project interfering'n'trashing tool
  24.  *
  25.  *-------------------------------------------------------------------
  26.  *
  27.  * hsctools/hscpitt.c
  28.  *
  29.  * updated: 14-Oct-1997
  30.  * created: 15-Oct-1996
  31.  */
  32.  
  33. /* ANSI includes */
  34. #include <stdio.h>
  35. #include <errno.h>
  36. #include <string.h>
  37. #include <time.h>
  38.  
  39. /* include revision data */
  40. #include "hsctools/pitt_rev.h"
  41.  
  42. /* ugly includes */
  43. #include "ugly/ustring.h"
  44. #include "ugly/dllist.h"
  45. #include "ugly/expstr.h"
  46. #include "ugly/infile.h"
  47. #include "ugly/ufile.h"
  48. #include "ugly/uargs.h"
  49. #include "ugly/ustrlist.h"
  50. #include "ugly/prginfo.h"
  51. #include "ugly/returncd.h"
  52.  
  53. /* hsclib includes */
  54. #include "hscprj/document.h"
  55. #include "hscprj/project.h"
  56. #include "hscprj/license.h"
  57.  
  58. #ifdef AMIGA
  59. /* AmigaOS version string
  60.  * (imported from "pitt_rev.h")
  61.  */
  62. static const STRPTR AmigaOS_version = VERSTAG;
  63. #endif
  64.  
  65. /* prefix for messages */
  66. #define HP ""
  67. #define DHP "*hscpit* "
  68. #define SHIT "*** "             /* prefix for total failure */
  69.  
  70. /* debugging define */
  71. #ifdef DEBUG
  72. #undef DEBUG
  73. #define DEBUG 1
  74. #endif
  75.  
  76. #ifdef D
  77. #undef D
  78. #endif
  79.  
  80. #if DEBUG
  81. #define D(x) if (debug) {x;}
  82. #else
  83. #define D(x) {/*nufin*/}
  84. #endif
  85.  
  86. /* default parameters */
  87. #define DEFAULT_PROJECT "hsc.project"   /* project-filename */
  88.  
  89. /* commands supported */
  90. #define CMD_COUNT_STR   "count"
  91. #define CMD_LIST_STR    "list"
  92. #define CMD_EXTRACT_STR "extract"
  93. #define CMD_DELETE_STR  "delete"
  94. #define CMD_ERASE_STR   "erase"
  95. #define CMD_ADD_STR     "add"
  96. #define CMD_NEW_STR     "new"
  97. #define CMD_COPY_STR    "copy"
  98. #define CMD_MOVE_STR    "move"
  99.  
  100. #define COMMAND_NONE    0
  101. #define COMMAND_COUNT   1
  102. #define COMMAND_LIST    2
  103. #define COMMAND_EXTRACT 3
  104. #define COMMAND_DELETE  4
  105. #define COMMAND_ERASE   5
  106. #define COMMAND_ADD     6
  107. #define COMMAND_NEW     7
  108. #define COMMAND_COPY    8
  109. #define COMMAND_MOVE    9
  110.  
  111. #define COMMAND_ENUMSTR     \
  112.         CMD_COUNT_STR   "|" \
  113.         CMD_LIST_STR    "|" \
  114.         CMD_EXTRACT_STR "|" \
  115.         CMD_DELETE_STR  "|" \
  116.         CMD_ERASE_STR   "|" \
  117.         CMD_ADD_STR     "|" \
  118.         CMD_NEW_STR
  119.  
  120. /*
  121.  * global vars
  122.  */
  123.  
  124. /* command strings */
  125. static STRPTR command_name[] =
  126. {
  127.     "***NONE***",
  128.     CMD_COUNT_STR,
  129.     CMD_LIST_STR,
  130.     CMD_EXTRACT_STR,
  131.     CMD_DELETE_STR,
  132.     CMD_ERASE_STR,
  133.     CMD_ADD_STR,
  134.     CMD_NEW_STR,
  135.     NULL
  136. };
  137.  
  138. static int return_code = RC_FAIL;       /* exit code of program */
  139.  
  140. static STRPTR prjfile = NULL;
  141. static LONG command = COMMAND_LIST;
  142. static LONG cmdArgNum = 0;      /* number of args for command (ARG/M) */
  143. static DLLIST *command_arglist = NULL;
  144. static BOOL force = FALSE;
  145. static BOOL quiet = FALSE;
  146. static BOOL debug = FALSE;
  147. static BOOL arg_help = FALSE;
  148. static BOOL arg_license = FALSE;
  149.  
  150. static HSCPRJ *project = NULL;
  151.  
  152. /*
  153.  * cleanup: free all resources
  154.  * (called in any case)
  155.  */
  156. static VOID cleanup(VOID)
  157. {
  158.     D(fprintf(stderr, "(cleanup)\r"));
  159.     del_dllist(command_arglist);
  160.     del_project(project);
  161.     D(fprintf(stderr, "         \r"));
  162. }
  163.  
  164. static VOID set_return_code(int new_code)
  165. {
  166.     if (new_code > return_code)
  167.         return_code = new_code;
  168. }
  169.  
  170. /*
  171.  * hsc_nomem_handler
  172.  *
  173.  * called from ugly/umalloc, if malloc() did return NULL
  174.  */
  175. static BOOL hscpitt_nomem_handler(size_t size)
  176. {
  177.     fputs(SHIT "out of memory\n", stderr);
  178.  
  179.     return_code = RC_FAIL;
  180.     exit(return_code);          /* abort immediatly */
  181.  
  182.     return (FALSE);
  183. }
  184.  
  185. VOID msg_corrupt_pf(HSCPRJ * hp, STRPTR reason)
  186. {
  187.     fprintf(stderr, "project-file corrupt: %s\n", reason);
  188.     set_return_code(RC_ERROR);
  189. }
  190.  
  191. /*
  192.  * update_project_file
  193.  *
  194.  * write updated project file, handle errors
  195.  */
  196. BOOL update_project_file(HSCPRJ * project)
  197. {
  198.     BOOL ok = FALSE;
  199.  
  200.     D(fprintf(stderr, DHP "update_project_file()\n"));
  201.     /* TODO: create backup */
  202.  
  203.     errno = 0;
  204.     ok = hsc_project_write_data(project, prjfile, TRUE);
  205.  
  206.     if (!ok)
  207.     {
  208.         fprintf(stderr, HP "error writing `%s'", prjfile);
  209.         if (errno)
  210.             fprintf(stderr, HP ": %s", strerror(errno));
  211.         fprintf(stderr, "\n");
  212.         set_return_code(RC_ERROR);
  213.     }
  214.  
  215.     return (ok);
  216. }
  217.  
  218. /*-------------------------------------------------------------------
  219.  *
  220.  * functions for arguments
  221.  *
  222.  *-------------------------------------------------------------------*/
  223.  
  224. /*
  225.  * check_min_cmd_args
  226.  *
  227.  * check, if at least a specific num of args has been specified
  228.  * for the command
  229.  */
  230. BOOL check_min_cmd_args(LONG minArgNum, DLLIST * list)
  231. {
  232.     BOOL ok = TRUE;
  233.     DLNODE *nd = dll_first(list);
  234.     LONG argNum = 0;
  235.  
  236.     /* count arguments */
  237.     while (nd)
  238.     {
  239.         argNum++;
  240.         nd = dln_next(nd);
  241.     }
  242.  
  243.     if (argNum < minArgNum)
  244.     {
  245.         fprintf(stderr, "command %s requires at least %ld arguments\n",
  246.                 command_name[command], minArgNum);
  247.         ok = FALSE;
  248.     }
  249.  
  250.     return (ok);
  251. }
  252.  
  253. /*
  254.  * args_ok
  255.  *
  256.  * prepare args, check & parse user args, display error and
  257.  * help message if neccessary
  258.  *
  259.  * result: TRUE, if all args ok and no request for HELP or
  260.  *         LICENSE has been detected
  261.  */
  262. static BOOL args_ok(int argc, char *argv[])
  263. {
  264.     struct arglist *hscpitt_args;       /* argument structure */
  265.     BOOL arg_help = FALSE;
  266.     BOOL arg_license = FALSE;
  267.     BOOL ok = FALSE;
  268.  
  269.     /* create arg-table */
  270.     hscpitt_args = prepare_args
  271.         ("HSCPITT_ARGS",
  272.          "COMMAND/E", COMMAND_ENUMSTR, &command,
  273.          "command to perform (" COMMAND_ENUMSTR ")",
  274.          "ARG/T/M", &command_arglist, "command argument(s)",
  275.          "PRJFILE/T/K", &prjfile, "project file",
  276.          "FORCE/S", &force, "disable certain checks",
  277.          "QUIET/S", &quiet, "act quietly",
  278.          "-DEBUG/S", &debug, "enable debugging output",
  279.          "HELP=?=-h=--help/S", &arg_help, "display this text",
  280.          "LICENSE/S", &arg_license, "display license",
  281.          NULL);
  282.  
  283.     ok = (hscpitt_args != NULL);
  284.  
  285.     /* set & test args */
  286.     if (ok)
  287.     {
  288.         ok = set_args(argc, argv, hscpitt_args);
  289.  
  290.         /* display argument error message */
  291.         if (!ok)
  292.         {
  293.             pargerr();
  294.             set_return_code(RC_ERROR);
  295.         }
  296.         else if (arg_help || arg_license)
  297.         {
  298.             /*
  299.              * display help or license text
  300.              */
  301.             fprintf_prginfo(stderr);
  302.             if (arg_help)
  303.                 fprintf_arghelp(stderr, hscpitt_args);
  304.             else
  305.                 show_license();
  306.             set_return_code(RC_WARN);
  307.             ok = FALSE;
  308.         }
  309.         else
  310.         {
  311.             /* display copyright in verbose-mode */
  312.             if (!quiet)
  313.                 fprintf_prginfo(stderr);
  314.  
  315.             /* set default-parameters if neccessary */
  316.             if (!prjfile)
  317.             {
  318.                 prjfile = DEFAULT_PROJECT;
  319.                 if (!quiet)
  320.                 {
  321.                     fprintf(stderr, HP "%s: using default project-file\n",
  322.                             prjfile);
  323.                 }
  324.             }
  325.  
  326.             if (command)
  327.             {
  328.                 /* debugging control output */
  329.                 D(
  330.                      {
  331.                      fprintf(stderr, DHP "prjfile =`%s'\n", prjfile);
  332.                      fprintf(stderr, DHP "command =`%ld'\n", command);
  333.                      }
  334.                 );
  335.             }
  336.             else
  337.             {
  338.                 fprintf(stderr, "no command specified\n");
  339.                 ok = FALSE;
  340.             }
  341.         }
  342.  
  343.         /* set error return code if neccessary */
  344.         if (!ok)
  345.         {
  346.             set_return_code(RC_ERROR);
  347.         }
  348.  
  349.         /* release mem used by args */
  350.         free_args(hscpitt_args);
  351.     }
  352.     else
  353.     {
  354.         /* only for developer */
  355.         D(fprintf(stderr, SHIT "ArgDef error: %lu\n", prep_error_num));
  356.     }
  357.  
  358. #if 1
  359.     return (ok);
  360. #else
  361.     return (FALSE);             /* for arg-debugging */
  362. #endif
  363. }
  364.  
  365. /*
  366.  * read_project
  367.  *
  368.  * read data from project file
  369.  */
  370. static BOOL read_project(VOID)
  371. {
  372.     BOOL ok = FALSE;
  373.     INFILE *inpf = NULL;
  374.  
  375.     if (!quiet)
  376.     {
  377.         fprintf(stderr, HP "%s: reading..\r", prjfile);
  378.         fflush(stderr);
  379.     }
  380.  
  381.     /* assign message-callback for corrupt project-file */
  382.     project->CB_msg_corrupt_pf = msg_corrupt_pf;
  383.  
  384.     /* read project-file */
  385.     errno = 0;
  386.     inpf = infopen(prjfile, 1024);
  387.     if (inpf)
  388.     {
  389.         if (hsc_project_read_data(project, inpf))
  390.         {
  391.             if (!quiet)
  392.             {
  393.                 fprintf(stderr, HP "%s: project-file read\n", prjfile);
  394.             }
  395.             ok = TRUE;
  396.         }
  397.         infclose(inpf);
  398.     }
  399.  
  400.     if (!ok)
  401.     {
  402.         fprintf(stderr, HP "error reading `%s'", prjfile);
  403.         if (errno)
  404.             fprintf(stderr, HP ": %s", strerror(errno));
  405.         fprintf(stderr, "\n");
  406.     }
  407.  
  408.     /* set error return code if neccessary */
  409.     if (!ok)
  410.     {
  411.         set_return_code(RC_ERROR);
  412.     }
  413.  
  414.     return (ok);
  415. }
  416.  
  417. /*-------------------------------------------------------------------
  418.  *
  419.  * functions for commands arguments
  420.  *
  421.  *-------------------------------------------------------------------*/
  422.  
  423. /* check for no args */
  424. static BOOL chkArg0(STRPTR command)
  425. {
  426.     BOOL ok = TRUE;
  427.     if (cmdArgNum)
  428.     {
  429.         fprintf(stderr, "no arguments allowed for command `%s'\n", command);
  430.         set_return_code(RC_ERROR);
  431.         ok = FALSE;
  432.     }
  433.     return (ok);
  434. }
  435.  
  436. /* check for two args */
  437. static BOOL chkArg2(STRPTR command, STRPTR arg1, STRPTR arg2)
  438. {
  439.     BOOL ok = TRUE;
  440.     if (cmdArgNum != 2)
  441.     {
  442.         fprintf(stderr, "two arguments required for command `%s': "
  443.                 "%s and %s\n", command, arg1, arg2);
  444.         set_return_code(RC_ERROR);
  445.         ok = FALSE;
  446.     }
  447.     return (ok);
  448. }
  449.  
  450. /* check for at least one arg (or more) */
  451. static BOOL chkArgAny(STRPTR command)
  452. {
  453.     BOOL ok = TRUE;
  454.     if (!cmdArgNum)
  455.     {
  456.         fprintf(stderr, "arguments required for command `%s'\n", command);
  457.         set_return_code(RC_ERROR);
  458.         ok = FALSE;
  459.     }
  460.     return (ok);
  461. }
  462.  
  463. /*-------------------------------------------------------------------
  464.  *
  465.  * functions for commands
  466.  *
  467.  *-------------------------------------------------------------------*/
  468.  
  469. /*-------------------------------------------------------------------*/
  470.  
  471. /*
  472.  * command_new
  473.  *
  474.  * write an empty project file
  475.  */
  476. BOOL command_new(HSCPRJ * project, DLLIST * arglist)
  477. {
  478.     BOOL ok = TRUE;
  479.  
  480.     if (chkArg0(CMD_NEW_STR))
  481.     {
  482.         if (fexists(prjfile) && !force)
  483.         {
  484.             printf("project file `%s' already exists\n", prjfile);
  485.             set_return_code(RC_ERROR);
  486.             ok = FALSE;
  487.         }
  488.         else
  489.         {
  490.             /* write new project file */
  491.             if (update_project_file(project))
  492.             {
  493.                 if (!quiet)
  494.                 {
  495.                     printf("Created new project file `%s'\n", prjfile);
  496.                 }
  497.             }
  498.         }
  499.     }
  500.  
  501.     return (ok);
  502. }
  503.  
  504. /*-------------------------------------------------------------------*/
  505.  
  506. /*
  507.  * command_add
  508.  *
  509.  * add new document and source to project
  510.  */
  511. VOID command_add(HSCPRJ * project, DLLIST * arglist)
  512. {
  513.     if (chkArg2(CMD_ADD_STR, "DOCUMENT", "SOURCE"))
  514.     {
  515.         BOOL deleted = FALSE;
  516.         DLNODE *docNameNd = dll_first(arglist);
  517.         DLNODE *docSourceNd = dln_next(docNameNd);
  518.         STRPTR docName = (STRPTR) dln_data(docNameNd);
  519.         STRPTR docSource = (STRPTR) dln_data(docSourceNd);
  520.  
  521.         /* try to remove document */
  522.         deleted = hsc_project_del_document(project, docName);
  523.  
  524.         if (!deleted || force)
  525.         {
  526.             D(fprintf(stderr, DHP " add doc=`%s'\n    src=`%s'\n",
  527.                       docName, docSource));
  528.  
  529.             /* set document as current document */
  530.             hsc_project_set_document(project, docName);
  531.             hsc_project_set_source(project, docSource);
  532.             hsc_project_add_document(project);
  533.  
  534.             /* update project file */
  535.             if (update_project_file(project))
  536.             {
  537.                 if (!quiet)
  538.                 {
  539.                     STRPTR operation = "Added";
  540.                     if (deleted)
  541.                     {
  542.                          operation = "Replaced";
  543.                     }
  544.                     printf("%s document `%s'\n", operation, docName);
  545.                 }
  546.             }
  547.         }
  548.         else
  549.         {
  550.             printf("Document `%s' already in project\n", docName);
  551.             set_return_code(RC_WARN);
  552.         }
  553.     }
  554. }
  555.  
  556. /*-------------------------------------------------------------------*/
  557.  
  558. /*
  559.  * command_delete
  560.  *
  561.  * remove document(s) from project
  562.  */
  563. VOID command_delete(HSCPRJ * project, DLLIST * arglist)
  564. {
  565.     if (chkArgAny(CMD_DELETE_STR))
  566.     {
  567.         DLNODE *docNode = dll_first(arglist);
  568.  
  569.         while (docNode)
  570.         {
  571.             STRPTR docName = (STRPTR) dln_data(docNode);
  572.             BOOL deleted = FALSE;
  573.  
  574.             /* remove document */
  575.             deleted = hsc_project_del_document(project, docName);
  576.  
  577.             /* output message */
  578.             if (deleted)
  579.             {
  580.                 if (!quiet)
  581.                 {
  582.                     printf("Delete `%s'\n", docName);
  583.                 }
  584.             }
  585.             else
  586.             {
  587.                 printf("Delete `%s': no such document\n", docName);
  588.                 set_return_code(RC_WARN);
  589.             }
  590.             docNode = dln_next(docNode);
  591.         }
  592.  
  593.         /* update project file */
  594.         update_project_file(project);
  595.     }
  596. }
  597.  
  598. /*-------------------------------------------------------------------*/
  599.  
  600. /*
  601.  * command_erase
  602.  *
  603.  * remove document(s) and corresponding files from project
  604.  */
  605. static BOOL uremove(STRPTR fname)
  606. {
  607.     BOOL erased = FALSE;
  608.  
  609.     /* TODO: convert URI to filename */
  610.     errno = 0;
  611.     erased = !remove(fname);
  612.     if (erased)
  613.     {
  614.         if (!quiet)
  615.         {
  616.             printf("Delete `%s'\n", fname);
  617.         }
  618.     }
  619.     else
  620.     {
  621.         printf("Error deleting `%s': %s\n", fname, strerror(errno));
  622.     }
  623.  
  624.     return (erased);
  625. }
  626.  
  627. VOID command_erase(HSCPRJ * project, DLLIST * arglist)
  628. {
  629.     if (chkArgAny(CMD_ERASE_STR))
  630.     {
  631.         DLNODE *argNode = dll_first(arglist);
  632.         BOOL erasedAny = FALSE;
  633.  
  634.         while (argNode)
  635.         {
  636.             STRPTR docName = (STRPTR) dln_data(argNode);
  637.             HSCDOC *document = find_document(project->documents, docName);
  638.             BOOL erased = FALSE;
  639.  
  640.             /* remove document and source file */
  641.             if (document)
  642.             {
  643.                 uremove(document->docname);
  644.                 uremove(document->sourcename);
  645.                 erased = hsc_project_del_document(project, docName);
  646.                 if (!erased)
  647.                     panic("no document entry");
  648.             }
  649.  
  650.             /* output message */
  651.             if (!erased)
  652.             {
  653.                 printf("Delete `%s': no such document\n", docName);
  654.                 set_return_code(RC_WARN);
  655.             }
  656.             else
  657.             {
  658.                 /* project file needs to be updated */
  659.                 erasedAny = TRUE;
  660.             }
  661.  
  662.             argNode = dln_next(argNode);
  663.         }
  664.  
  665.         /* update project file */
  666.         if (erasedAny)
  667.         {
  668.             update_project_file(project);
  669.         }
  670.     }
  671. }
  672.  
  673. /*-------------------------------------------------------------------*/
  674.  
  675. /*
  676.  * command_extract
  677.  *
  678.  * display detailed information about documents found in project
  679.  */
  680. static VOID printfVar(STRPTR var, STRPTR value)
  681. {
  682.     if (!value)
  683.         value = "";
  684.     printf("%s=\"%s\"\n", var, value);
  685. }
  686.  
  687. static VOID extract_document(HSCPRJ * project, HSCDOC * document, BOOL emptyLine)
  688. {
  689.     /* show empty line; not for first document */
  690.     if (emptyLine)
  691.     {
  692.         puts("");
  693.     }
  694.  
  695.     /* display document name and source used */
  696.     printfVar("DOCUMENT", document->docname);
  697.     printfVar("SOURCE", document->sourcename);
  698.  
  699. #if 1
  700.     /* display includes */
  701.     if (document->includes)
  702.     {
  703.         DLNODE *nd = dll_first(document->includes);
  704.         while (nd)
  705.         {
  706.             HSCINC *include = (HSCINC *) dln_data(nd);
  707.             printfVar("INCLUDE", include->name);
  708.             nd = dln_next(nd);
  709.         }
  710.     }
  711. #endif
  712. }
  713.  
  714. VOID command_extract(HSCPRJ * project, DLLIST * arglist)
  715. {
  716.     if (cmdArgNum)
  717.     {
  718.         /* extract document(s) specified in args */
  719.         DLNODE *argNode = dll_first(arglist);
  720.         BOOL emptyLine = FALSE;
  721.  
  722.         while (argNode)
  723.         {
  724.             STRPTR docName = (STRPTR) dln_data(argNode);
  725.             HSCDOC *document = find_document(project->documents, docName);
  726.  
  727.             /* remove document and source file */
  728.             if (document)
  729.             {
  730.                 extract_document(project, document, emptyLine);
  731.                 emptyLine = TRUE;
  732.             }
  733.             else
  734.             {
  735.                 fprintf(stderr, "Extract `%s': no such document\n", docName);
  736.                 set_return_code(RC_WARN);
  737.             }
  738.  
  739.             argNode = dln_next(argNode);
  740.         }
  741.     }
  742.     else
  743.     {
  744.         /* extract all documents */
  745.         DLNODE *docNode = dll_first(project->documents);
  746.         BOOL emptyLine = FALSE;
  747.  
  748.         while (docNode)
  749.         {
  750.             HSCDOC *document = (HSCDOC *) dln_data(docNode);
  751.  
  752.             extract_document(project, document, emptyLine);
  753.             emptyLine = TRUE;
  754.  
  755.             /* process next node, show empty line if
  756.              * further data exist */
  757.             docNode = dln_next(docNode);
  758.         }
  759.     }
  760. }
  761.  
  762. /*-------------------------------------------------------------------*/
  763.  
  764. /*
  765.  * command_count
  766.  *
  767.  * display number of documents currently stored in project file
  768.  */
  769. VOID command_count(HSCPRJ * project, DLLIST * arglist)
  770. {
  771.     DLNODE *docNode = dll_first(project->documents);
  772.     ULONG docNum = 0;
  773.  
  774.     if (chkArg0(CMD_COUNT_STR))
  775.     {
  776.         while (docNode)
  777.         {
  778.             docNum++;
  779.             docNode = dln_next(docNode);
  780.         }
  781.  
  782.         /* display number of documents */
  783.         printf("%lu\n", docNum);
  784.     }
  785. }
  786.  
  787. /*-------------------------------------------------------------------*/
  788.  
  789. /*
  790.  * command_list
  791.  *
  792.  * display list of documents found in project
  793.  */
  794. VOID command_list(HSCPRJ * project, DLLIST * arglist)
  795. {
  796.     if (chkArg0(CMD_COUNT_STR))
  797.     {
  798.         DLNODE *docNode = dll_first(project->documents);
  799.  
  800.         while (docNode)
  801.         {
  802.             HSCDOC *document = (HSCDOC *) dln_data(docNode);
  803.  
  804.             printf("%s\n", document->docname);
  805.             docNode = dln_next(docNode);
  806.         }
  807.     }
  808. }
  809.  
  810. /*-------------------------------------------------------------------*/
  811.  
  812. /*
  813.  * process_command
  814.  *
  815.  */
  816. BOOL process_command(HSCPRJ * project, LONG command, DLLIST * arglist)
  817. {
  818.     BOOL ok = TRUE;
  819.     DLNODE *nd = NULL;
  820.  
  821.     D(fprintf(stderr, DHP "process_command()\n"));
  822.     D(fprintf(stderr, DHP "command: %s\n", command_name[command]));
  823.  
  824.     /* count number of args */
  825.     if (arglist)
  826.         nd = dll_first(arglist);
  827.     if (nd)
  828.     {
  829.         D(fprintf(stderr, DHP "command args:\n"));
  830.         while (nd)
  831.         {
  832.             D(fprintf(stderr, DHP "  `%s'\n", (STRPTR) dln_data(nd)));
  833.             cmdArgNum++;
  834.             nd = dln_next(nd);
  835.         }
  836.     }
  837.     else
  838.     {
  839.         D(fprintf(stderr, DHP "command args: NONE\n"));
  840.     }
  841.     D(fprintf(stderr, DHP "cmdarg#: %ld\n", cmdArgNum));
  842.  
  843.     switch (command)
  844.     {
  845.     case COMMAND_COUNT:
  846.         command_count(project, arglist);
  847.         break;
  848.     case COMMAND_LIST:
  849.         command_list(project, arglist);
  850.         break;
  851.     case COMMAND_EXTRACT:
  852.         command_extract(project, arglist);
  853.         break;
  854.     case COMMAND_DELETE:
  855.         command_delete(project, arglist);
  856.         break;
  857.     case COMMAND_ERASE:
  858.         command_erase(project, arglist);
  859.         break;
  860.     case COMMAND_ADD:
  861.         command_add(project, arglist);
  862.         break;
  863.     case COMMAND_NEW:
  864.         ok = command_new(project, arglist);
  865.         break;
  866.     default:
  867.         {
  868.             D(fprintf(stderr, DHP "unknown command\n"));
  869.             ok = FALSE;
  870.             break;
  871.         }
  872.     }
  873.  
  874.     return (ok);
  875. }
  876.  
  877. /*-------------------------------------------------------------------
  878.  *
  879.  * main function
  880.  *
  881.  *-------------------------------------------------------------------*/
  882. int main(int argc, char *argv[])
  883. {
  884. #ifndef BETA
  885. #define BETA 0
  886. #endif
  887.     /* set program information */
  888.     set_prginfo("hscpitt", UGLY_AUTHOR, VERSION, REVISION, BETA,
  889.                 "hsc project interfering'n'trashing tool",
  890.                 "Freeware, type `hscpitt LICENSE' for details.");
  891.  
  892. #if DEBUG
  893.     /* display a memory tracking report */
  894.     /* at end of execution */
  895.     atexit(atexit_uglymemory);
  896. #endif
  897.  
  898.     /* install nomem-handler */
  899.     ugly_nomem_handler = hscpitt_nomem_handler;
  900.  
  901.     /* use cleanup() as additional exit func */
  902.     if (!atexit(cleanup))
  903.     {
  904.         /*
  905.          * main procedure
  906.          */
  907.         return_code = RC_OK;
  908.         project = new_project();
  909.         if (project && args_ok(argc, argv))
  910.         {
  911.             BOOL ok = TRUE;
  912.  
  913.             if (command != COMMAND_NEW)
  914.             {
  915.                 ok = read_project();
  916.             }
  917.  
  918.             if (ok && process_command(project, command, command_arglist))
  919.             {
  920.                 return_code = RC_OK;
  921.             }
  922.         }
  923.     }
  924.     else
  925.     {
  926.         fputs(SHIT "atexit() failed ", stderr);
  927.     }
  928.     return (return_code);
  929. }
  930.  
  931.